Next | Prev | Up | Top | Contents | Index
Asynchronous I/O Basics
A real-time process needs to read or write a device, but it cannot tolerate an unpredictable delay. One obvious solution can be summarized as "call read() or write() from a different process, and run that process in a different CPU." This is the essence of asynchronous I/O. You could implement an asynchronous I/O scheme of your own design, and you may wish to do so in order to integrate the I/O closely with your own design of processes and data structures. However, a standard solution is available.
Two Implementation Versions
IRIX (since version 5.3) supports asynchronous I/O library calls conforming to POSIX document 1003.1b-1993. You use relatively simple calls to initiate input or output. The library package handles the details of
- initiating several lightweight processes to perform I/O
- allocating a shared memory arena and the locks, semaphores, and/or queues used to coordinate between the I/O processes
- queueing multiple input or output requests to each of multiple file descriptors
- reporting results back to your processes, either on request, through signals, or through callback functions
Note: In IRIX 5.2 and IRIX 6.0, asynchronous I/O was implemented to conform to POSIX standard 1003.4 Draft 12, an earlier document. Support for the later POSIX standard1003.1b was implemented in IRIX 5.3. Programs compiled in IRIX 5.2 continue to work in later releases. However, conversion of programs to POSIX standard1003.1b is recommended. The remainder of this topic describes that interface.
Only in IRIX 5.3, both the Draft-12 and 1003.1b interfaces were supported. In that release, you had to take two steps to compile with the later version of asynchronous I/O:
- Define the compiler variable _ABI_SOURCE. This indicates conformance with the MIPS Application Binary Interface.
- Include the library parameter -labi in the link.
In releases following 5.3, support for POSIX 1003.1b-1993 is the only version of asynchronous I/O. These steps are no longer required. It is no longer possible to compile programs that use the Draft-12 interface.
Asynchronous I/O Functions
Once you have opened the files and initialized asynchronous I/O, you perform asynchronous I/O by calling some of these functions:
aio_read(3) | Initiates asynchronous input from a file or device. |
aio_write(3) | Initiates asynchronous output to a file or device. |
lio_listio(3) | Initiates a list of operations to one or more files or devices. |
aio_error(3) | Returns the status of an asynchronous operation. |
aio_fsync(3) | Waits for all scheduled output for a file to complete. |
aio_cancel(3) | Cancels pending, scheduled operations. |
Each of these functions is described in detail in a reference page in volume 3.
Asynchronous I/O Control Block
Each asynchronous I/O request is represented by an instance of struct aiocb, a data structure that your program must allocate. The important fields are as follows.
- The file descriptor that is the target of the operation.
File descriptors are returned by open() (see the open(2) reference page). A file descriptor used for asynchronous I/O can represent any file or device--not only a disk file.
- The address and size of a buffer to supply or receive the data.
- The file position for the operation as it would be passed to lseek() (see the lseek(2) reference page)
The use of this value is discussed under "Multiple Operations to One File".
- A sigevent structure, whose contents indicate what, if anything, should be done to notify your program of the completion of the I/O.
The use of the sigevent is discussed under "Checking for Completion".
Note: The IRIX 5.2 implementation also accepted a request priority value. Request priorities are no longer supported. The field exists for compatibility and for possible future use, but must currently contain zero.
Next | Prev | Up | Top | Contents | Index